package net.pws.oos.web;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import net.pws.common.util.StringUtils;
import net.pws.common.jackson.JsonUtils;
import net.pws.common.persistence.EntityManager;
import net.pws.common.security.SecurityContext;
import net.pws.common.security.spi.resource.Resource;
import net.pws.oos.biz.model.Organization;
import net.pws.oos.biz.model.Phone;
import net.pws.oos.biz.model.Role;
import net.pws.oos.biz.model.User;
import net.pws.oos.biz.query.PhoneQuery;
import net.pws.oos.biz.query.SystemManageFinder;
import net.pws.oos.biz.query.parameter.OperateLogQueryParameter;
import net.pws.oos.biz.query.parameter.OrganizationQueryParameter;
import net.pws.oos.biz.query.parameter.PhoneQueryParameter;
import net.pws.oos.biz.query.parameter.ResourceQueryParameter;
import net.pws.oos.biz.query.parameter.RoleQueryParameter;
import net.pws.oos.biz.query.parameter.UserQueryParameter;
import net.pws.oos.biz.service.SystemManageService;
import net.pws.oos.security.SecurityUtils;
import net.pws.oos.web.dto.OperateLogDto;
import net.pws.oos.web.dto.OrganizationDto;
import net.pws.oos.web.dto.OrganizationTreeNodeDto;
import net.pws.oos.web.dto.PermissionTreeNodeDto;
import net.pws.oos.web.dto.ResourceDto;
import net.pws.oos.web.dto.ResourceTreeNodeDto;
import net.pws.oos.web.dto.RoleDto;
import net.pws.oos.web.dto.TreeNode;
import net.pws.oos.web.dto.UserDto;
import net.pws.oos.web.dto.UserTreeNodeDto;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * 系统管理，组织管理，用户管理，角色管理，权限管理
 */
@Controller
@RequestMapping("/biz/system")
@SuppressWarnings({ "rawtypes", "unchecked" })
public class SystemManageAction {
    
    public final transient Log logger = LogFactory.getLog(SystemManageAction.class);
    
    @Autowired
    private SystemManageService systemManageService;
    
    @Autowired
    private SystemManageFinder systemManageFinder;
    
    @Autowired
    private PhoneQuery phoneQuery;
    
    @Autowired
    private EntityManager entityManager;
    
    @RequestMapping("/user/count.json")
    @ResponseBody
    public Object getUserCount(UserQueryParameter queryParams) {
        if (queryParams == null) {
            queryParams = new UserQueryParameter();
        }
        Map map = new HashMap();
        try {
            map.put("data", systemManageFinder.countUser(queryParams));
            map.put("succeed", Boolean.TRUE);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
        
        return map;
    }
    
    @RequestMapping("/user/list.json")
    @ResponseBody
    public Object getUserList(UserQueryParameter queryParams) {
        if (queryParams == null) {
            queryParams = new UserQueryParameter();
        }
        Map map = new HashMap();
        try {
            List<Map> users = systemManageFinder.getUserMapList(queryParams,
                                                                queryParams.getStart(),
                                                                queryParams.getLimit());
            
            map.put("data", users);
            map.put("succeed", Boolean.TRUE);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
        
        return map;
    }
    
    @RequestMapping("/user/excel.do")
    public Object exportUserList(UserQueryParameter queryParams, ModelMap map) {
        queryParams = initUserParameterByRole(queryParams);
        queryParams.setLimit(Integer.MAX_VALUE);
        List<Map> users = systemManageFinder.listUserWithRoles(queryParams);
        map.put("users", users);
        
        return "system/user/excel";
    }
    
    @RequestMapping("/user/list.do")
    public Object getUserList(ModelMap map) {
        RoleQueryParameter queryParameter = new RoleQueryParameter();
        List<Role> roles = systemManageFinder.getRoleList(queryParameter,
                                                          0,
                                                          Integer.MAX_VALUE);
        map.put("roles", roles);
        return "system/user/list";
    }
    
    @RequestMapping("/user/ourCount.json")
    @ResponseBody
    public Object getOurUserCount(UserQueryParameter queryParams) {
        queryParams = initUserParameterByRole(queryParams);
        Map map = new HashMap();
        try {
            map.put("data", systemManageFinder.countUserWithRoles(queryParams));
            map.put("succeed", Boolean.TRUE);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
        
        return map;
    }
    
    @RequestMapping("/user/ourList.json")
    @ResponseBody
    public Object getOurUserList(UserQueryParameter queryParams) {
        queryParams = initUserParameterByRole(queryParams);
        Map map = new HashMap();
        try {
            List<Map> users = systemManageFinder.listUserWithRoles(queryParams);
            
            map.put("data", users);
            map.put("succeed", Boolean.TRUE);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
        
        return map;
    }
    
    private UserQueryParameter initUserParameterByRole(UserQueryParameter queryParameter) {
        if (queryParameter == null) {
            queryParameter = new UserQueryParameter();
        }
        
        if (StringUtils.isBlank(queryParameter.getOrganId())) {
            queryParameter.setOrganId(SecurityUtils.currentUser().getOrganId());
        }
        return queryParameter;
    }
    
    @RequestMapping("/user/edit.do")
    public String prepareEditUser(String id, ModelMap map) {
        
        if (StringUtils.isEmpty(id)) {
            UserDto dto = new UserDto();
            dto.setWebAccessAllowed(true);
            dto.setMobileAccessAllowed(true);
            map.put("data", dto);
            return "system/user/new";
        }
        map.put("data", UserDto.from(systemManageFinder.getUserMap(id)));
        return "system/user/edit";
    }
    
    @RequestMapping("/user/detail.do")
    public Object getUserDetail(String id, ModelMap map) {
        try {
            map.put("data", UserDto.from(systemManageFinder.getUser(id)));
            map.put("succeed", Boolean.TRUE);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
        return "system/user/detail";
    }
    
    @RequestMapping("/user/detail.json")
    @ResponseBody
    public Object getUserDetail(String id) {
        Map map = new HashMap();
        if (StringUtils.isEmpty(id)) {
            map.put("succeed", Boolean.FALSE);
            map.put("message", "id不能为空！");
            return map;
        }
        try {
            map.put("data", UserDto.from(systemManageFinder.getUser(id)));
            map.put("succeed", Boolean.TRUE);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
        return map;
    }
    
    @RequestMapping("/user/save.json")
    @ResponseBody
    public Object saveUser(UserDto dto) {
        try {
            if (StringUtils.isEmpty(dto.getId())) {
                return JsonUtils.succeedMap(UserDto.from(systemManageService.saveUser(UserDto.to(dto,
                                                                                                 entityManager))));
            }
            return JsonUtils.succeedMap(UserDto.from(systemManageService.saveUser(UserDto.to(dto,
                                                                                             entityManager))));
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    @RequestMapping("/user/delete.json")
    @ResponseBody
    public Object removeUser(String id) {
        try {
            if (StringUtils.isEmpty(id)) {
                throw new IllegalArgumentException("用户ID为空！");
            }
            
            User user = entityManager.find(User.class, id);
            if (null == user) {
                return JsonUtils.succeedMap(null);
            }
            
            if (!StringUtils.isEmpty(user.getSourceSystem())) {
                throw new RuntimeException("不能删除同步自其他系统的用户！");
            }
            
            systemManageService.deleteUser(id);
            return JsonUtils.succeedMap(null);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    @RequestMapping("/user/tree.json")
    @ResponseBody
    public Object getUserTree(String id, HttpServletRequest request) {
        try {
            List<TreeNode> nodes = new ArrayList<TreeNode>();
            if (StringUtils.isBlank(id)) {
                if (SecurityUtils.isManager()) {
                    id = SecurityUtils.currentUser().getOrganId();
                    Organization org = entityManager.find(Organization.class,
                                                          id);
                    nodes.add(OrganizationTreeNodeDto.from(org, request));
                }
                else {
                    nodes.add(UserTreeNodeDto.from(SecurityUtils.currentUser(),
                                                   request));
                }
            }
            else {
                List<Organization> organs = systemManageFinder.getOrganizationChildren(id);
                List<User> users = systemManageFinder.getUserListByOrgan(id);
                for (Organization organization : organs) {
                    nodes.add(OrganizationTreeNodeDto.from(organization,
                                                           request));
                }
                for (User user : users) {
                    nodes.add(UserTreeNodeDto.from(user, request));
                }
            }
            return JsonUtils.succeedMap(nodes);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    @RequestMapping("/user/phone.json")
    @ResponseBody
    public Object getUserPhones(String userId) {
        try {
            List<Phone> phones = phoneQuery.list(userId);
            return JsonUtils.succeedMap(phones);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    @RequestMapping("/user/phones.do")
    public String userPhonesPage() {
        return "system/user/phones";
    }
    
    @RequestMapping("/user/phone/list.json")
    @ResponseBody
    public Object listUserPhones(PhoneQueryParameter parameter) {
        parameter = initPhoneParameterByRole(parameter);
        try {
            return JsonUtils.succeedMap(phoneQuery.list(parameter));
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    @RequestMapping("/user/phone/count.json")
    @ResponseBody
    public Object countUserPhones(PhoneQueryParameter parameter) {
        parameter = initPhoneParameterByRole(parameter);
        try {
            return JsonUtils.succeedMap(phoneQuery.count(parameter));
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    private PhoneQueryParameter initPhoneParameterByRole(PhoneQueryParameter queryParams) {
        if (queryParams == null) {
            queryParams = new PhoneQueryParameter();
        }
        if (StringUtils.areEmpty(queryParams.getUserId(),
                                 queryParams.getOrganId())) {
            queryParams.setOrganId(SecurityUtils.currentUser().getOrganId());
        }
        
        return queryParams;
    }
    
    @RequestMapping("/admin/changePassword.json")
    @ResponseBody
    public Object changePassword(String id,
                                 String newPassword,
                                 String newPasswordRetry) {
        if (!newPassword.equals(newPasswordRetry)) {
            return JsonUtils.failedMap("两次新密码输入不一致！");
        }
        
        try {
            systemManageService.changeUserPassword(id, newPassword);
            return JsonUtils.succeedMap(null);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    @RequestMapping("/user/changePassword.json")
    @ResponseBody
    public Object changePassword(String id,
                                 String oldPassword,
                                 String newPassword,
                                 String newPasswordRetry) {
        try {
            if (!newPassword.equals(newPasswordRetry)) {
                return JsonUtils.failedMap("两次新密码输入不一致！");
            }
            if (id == null) {
                id = SecurityContext.getContext().getId();
            }
            systemManageService.changeUserPassword(id, oldPassword, newPassword);
            return JsonUtils.succeedMap(null);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    @RequestMapping("/user/bind/count.json")
    @ResponseBody
    public Object getBindedUserCount(RoleQueryParameter queryParams) {
        if (queryParams == null) {
            queryParams = new RoleQueryParameter();
        }
        try {
            return JsonUtils.succeedMap(systemManageFinder.countBindedUser(queryParams.getRoleId()));
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    @RequestMapping("/user/bind/list.json")
    @ResponseBody
    public Object getBindedUserList(RoleQueryParameter queryParams) {
        if (queryParams == null) {
            queryParams = new RoleQueryParameter();
        }
        try {
            List<Map> users = systemManageFinder.getBindedUserList(queryParams.getRoleId(),
                                                                   queryParams.getStart(),
                                                                   queryParams.getLimit());
            
            return JsonUtils.succeedMap(users);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    @RequestMapping("/user/unbind/count.json")
    @ResponseBody
    public Object getUnBindedUserCount(RoleQueryParameter queryParams) {
        if (queryParams == null) {
            queryParams = new RoleQueryParameter();
        }
        try {
            return JsonUtils.succeedMap(systemManageFinder.countUnbindedUser(queryParams));
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    @RequestMapping("/user/unbind/list.json")
    @ResponseBody
    public Object getUnBindedUserList(RoleQueryParameter queryParams) {
        if (queryParams == null) {
            queryParams = new RoleQueryParameter();
        }
        try {
            List<Map> users = systemManageFinder.getUnbindedUserList(queryParams,
                                                                     queryParams.getStart(),
                                                                     queryParams.getLimit());
            
            return JsonUtils.succeedMap(users);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    //
    @RequestMapping("/role/bind/count.json")
    @ResponseBody
    public Object getBindedRoleCount(UserQueryParameter queryParams) {
        if (queryParams == null) {
            queryParams = new UserQueryParameter();
        }
        try {
            return JsonUtils.succeedMap(systemManageFinder.countBindedRole(queryParams.getUserId()));
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    @RequestMapping("/role/bind/list.json")
    @ResponseBody
    public Object getBindedRoleList(UserQueryParameter queryParams) {
        if (queryParams == null) {
            queryParams = new UserQueryParameter();
        }
        try {
            List<Map> roles = systemManageFinder.getBindedRoleList(queryParams.getUserId(),
                                                                   queryParams.getStart(),
                                                                   queryParams.getLimit());
            
            return JsonUtils.succeedMap(roles);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    @RequestMapping("/role/unbind/count.json")
    @ResponseBody
    public Object getUnBindedRoleCount(UserQueryParameter queryParams) {
        if (queryParams == null) {
            queryParams = new UserQueryParameter();
        }
        try {
            return JsonUtils.succeedMap(systemManageFinder.countUnbindedRole(queryParams));
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    @RequestMapping("/role/unbind/list.json")
    @ResponseBody
    public Object getUnBindedRoleList(UserQueryParameter queryParams) {
        if (queryParams == null) {
            queryParams = new UserQueryParameter();
        }
        try {
            List<Map> roles = systemManageFinder.getUnbindedRoleList(queryParams,
                                                                     queryParams.getStart(),
                                                                     queryParams.getLimit());
            
            return JsonUtils.succeedMap(roles);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    @RequestMapping("/user/bindRole.json")
    @ResponseBody
    public Object bindUserRole(String userId, String roleIds) {
        try {
            String[] roleIdArray = roleIds.split(",");
            systemManageService.bindUserRole(userId, roleIdArray);
            return JsonUtils.succeedMap(null);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    @RequestMapping("/role/bindUser.json")
    @ResponseBody
    public Object bindRoleUser(String roleId, String userIds) {
        try {
            String[] userIdArray = userIds.split(",");
            systemManageService.bindRoleUser(roleId, userIdArray);
            return JsonUtils.succeedMap(null);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    @RequestMapping("/user/unbindRole.json")
    @ResponseBody
    public Object unbindUserRole(String userId, String roleIds) {
        try {
            String[] roleIdArray = roleIds.split(",");
            systemManageService.unbindUserRole(userId, roleIdArray);
            return JsonUtils.succeedMap(null);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    @RequestMapping("/role/unbindUser.json")
    @ResponseBody
    public Object unbindRoleUser(String roleId, String userIds) {
        try {
            String[] userIdArray = userIds.split(",");
            systemManageService.unbindRoleUser(roleId, userIdArray);
            return JsonUtils.succeedMap(null);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    @RequestMapping("/role/count.json")
    @ResponseBody
    public Object getRoleCount(RoleQueryParameter queryParams) {
        if (queryParams == null) {
            queryParams = new RoleQueryParameter();
        }
        Map map = new HashMap();
        try {
            map.put("data", systemManageFinder.countRole(queryParams));
            map.put("succeed", Boolean.TRUE);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
        return map;
    }
    
    @RequestMapping("/role/list.json")
    @ResponseBody
    public Object getRoleList(RoleQueryParameter queryParams) {
        if (queryParams == null) {
            queryParams = new RoleQueryParameter();
        }
        Map map = new HashMap();
        try {
            List<Role> roles = systemManageFinder.getRoleList(queryParams,
                                                              queryParams.getStart(),
                                                              queryParams.getLimit());
            
            List<RoleDto> roleDtos = new ArrayList<RoleDto>();
            for (Role role : roles) {
                roleDtos.add(RoleDto.from(role));
            }
            
            map.put("data", roleDtos);
            map.put("succeed", Boolean.TRUE);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
        
        return map;
    }
    
    @RequestMapping("/role/detail.json")
    @ResponseBody
    public Object getRoleDetail(String id) {
        try {
            if (StringUtils.isEmpty(id)) {
                throw new IllegalArgumentException("角色ID为空！");
            }
            
            Role role = systemManageFinder.getRole(id);
            return JsonUtils.succeedMap(RoleDto.from(role));
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    @RequestMapping("/role/edit.do")
    public String prepareEditRole(String id, ModelMap map) {
        if (StringUtils.isEmpty(id)) {
            return "system/role/new";
        }
        // map.put("data", RoleDto.from(systemManageService.getRole(id)));
        return "system/role/edit";
    }
    
    @RequestMapping("/role/save.json")
    @ResponseBody
    public Object saveRole(RoleDto dto) {
        Map map = new HashMap();
        try {
            map.put("data",
                    RoleDto.from(systemManageService.saveRole(RoleDto.to(dto))));
            map.put("succeed", Boolean.TRUE);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
        return map;
    }
    
    @RequestMapping("/role/delete.json")
    @ResponseBody
    public Object removeRole(String id) {
        try {
            if (StringUtils.isEmpty(id)) {
                throw new IllegalArgumentException("角色ID为空！");
            }
            systemManageService.deleteRole(id);
            return JsonUtils.succeedMap(null);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    @RequestMapping("/roles/delete.json")
    @ResponseBody
    public Object removeRoles(String ids) {
        try {
            if (StringUtils.isEmpty(ids)) {
                throw new IllegalArgumentException("角色ID为空！");
            }
            systemManageService.deleteRole(ids.split(","));
            return JsonUtils.succeedMap(null);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    @RequestMapping("/organ/count.json")
    @ResponseBody
    public Object getOrganizationCount(OrganizationQueryParameter queryParams) {
        queryParams = initOrganParameterByRole(queryParams);
        Map map = new HashMap();
        try {
            map.put("data", systemManageFinder.countOrganization(queryParams));
            map.put("succeed", Boolean.TRUE);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
        
        return map;
    }
    
    @RequestMapping("/organ/children.json")
    @ResponseBody
    public Object getOrganizationList(String id,
                                      String exclude,
                                      HttpServletRequest request) {
        try {
            List<Organization> organizations = null;
            if (StringUtils.isBlank(id)) {
                id = SecurityUtils.currentUser().getOrganId();
                Organization org = entityManager.find(Organization.class, id);
                organizations = new ArrayList<Organization>();
                organizations.add(org);
            }
            else {
                if (StringUtils.isEmpty(exclude)) {
                    organizations = systemManageFinder.getOrganizationChildren(id);
                }
                else {
                    organizations = systemManageFinder.getOrganizationChildren(id,
                                                                               exclude);
                }
            }
            
            List<OrganizationTreeNodeDto> organizationDtos = new ArrayList<OrganizationTreeNodeDto>();
            for (Organization organization : organizations) {
                organizationDtos.add(OrganizationTreeNodeDto.from(organization,
                                                                  request));
            }
            
            // map.put("data", organizationDtos);
            // map.put("succeed", Boolean.TRUE);
            // List<OrganizationTreeNodeDto> dtos = new
            // ArrayList<OrganizationTreeNodeDto>();
            // OrganizationTreeNodeDto a = new OrganizationTreeNodeDto();
            // a.setTitle("test");
            // dtos.add(a);
            return JsonUtils.succeedMap(organizationDtos);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    @RequestMapping("/organ/list.json")
    @ResponseBody
    public Object getOrganizationList(OrganizationQueryParameter queryParams) {
        queryParams = initOrganParameterByRole(queryParams);
        Map map = new HashMap();
        try {
            List<Map> organizations = systemManageFinder.getOrganizationMapList(queryParams,
                                                                                queryParams.getStart(),
                                                                                queryParams.getLimit());
            
            map.put("data", organizations);
            map.put("succeed", Boolean.TRUE);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
        return map;
    }
    
    @RequestMapping("/organ/ourCount.json")
    @ResponseBody
    public Object getOurOrganizationCount(OrganizationQueryParameter queryParams) {
        queryParams = initOrganParameterByRole(queryParams);
        try {
            return JsonUtils.succeedMap(systemManageFinder.countOurOrganization(queryParams));
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    @RequestMapping("/organ/ourList.json")
    @ResponseBody
    public Object getOurOrganizationList(OrganizationQueryParameter queryParams) {
        queryParams = initOrganParameterByRole(queryParams);
        try {
            List<Map> organizations = systemManageFinder.getOurOrganizationMapList(queryParams,
                                                                                   queryParams.getStart(),
                                                                                   queryParams.getLimit());
            return JsonUtils.succeedMap(organizations);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    private OrganizationQueryParameter initOrganParameterByRole(OrganizationQueryParameter queryParams) {
        if (queryParams == null) {
            queryParams = new OrganizationQueryParameter();
        }
        if (StringUtils.isEmpty(queryParams.getAncestorId())) {
            queryParams.setAncestorId(SecurityUtils.currentUser().getOrganId());
        }
        
        return queryParams;
    }
    
    @RequestMapping("/organ/detail.do")
    public String getOrganizationDetail(String id, ModelMap map) {
        try {
            
            map.put("data",
                    OrganizationDto.from(systemManageFinder.getOrganization(id)));
            map.put("succeed", Boolean.TRUE);
        }
        catch (Exception e) {
            logger.error(e, e);
            JsonUtils.failedMap(e.getMessage());
        }
        return "system/organ/detail";
    }
    
    @RequestMapping("/organ/detail.json")
    @ResponseBody
    public Object getOrganizationDetail(String id) {
        if (StringUtils.isEmpty(id)) {
            // 得到当前用户的组织机构
            UserDto user = SecurityUtils.currentUser();
            if (user == null) {
                return JsonUtils.failedMap("未找到当前用户！");
            }
            id = user.getOrganId();
        }
        
        try {
            OrganizationDto dto = OrganizationDto.from(systemManageFinder.getOrganization(id));
            return JsonUtils.succeedMap(dto);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    @RequestMapping("/organ/edit.do")
    public String prepareEditOrganization(String id, ModelMap map) {
        if (StringUtils.isEmpty(id)) {
            return "system/organ/detail";
        }
        map.put("data",
                OrganizationDto.from(systemManageFinder.getOrganizationMap(id)));
        return "system/organ/detail";
    }
    
    @RequestMapping("/organ/save.json")
    @ResponseBody
    public Object saveOrganization(OrganizationDto dto) {
        Map map = new HashMap();
        try {
            map.put("data",
                    OrganizationDto.from(systemManageService.saveOrganization(OrganizationDto.to(dto,
                                                                                                 entityManager))));
            map.put("succeed", Boolean.TRUE);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
        return map;
    }
    
    @RequestMapping("/organ/delete.json")
    @ResponseBody
    public Object removeOrganization(String id) {
        try {
            if (StringUtils.isEmpty(id)) {
                throw new IllegalArgumentException("建设单位ID为空！");
            }
            
            Organization organ = entityManager.find(Organization.class, id);
            if (null == organ) {
                return JsonUtils.succeedMap(null);
            }
            
            if (organ.getParent() == null) {
                throw new RuntimeException("不能删除顶级建设单位！");
            }
            
            if (!StringUtils.isEmpty(organ.getSourceSystem())) {
                throw new RuntimeException("不能删除同步自其他系统的建设单位！");
            }
            
            systemManageService.deleteOrganization(id);
            return JsonUtils.succeedMap(null);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    // resource[type='menu']
    @RequestMapping("/menu/count.json")
    @ResponseBody
    public Object getMenuCount(ResourceQueryParameter queryParams) {
        if (queryParams == null) {
            queryParams = new ResourceQueryParameter();
        }
        queryParams.setType("menu");
        Map map = new HashMap();
        try {
            map.put("data", systemManageService.getResourceCount());
            map.put("succeed", Boolean.TRUE);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
        
        return map;
    }
    
    @RequestMapping("/menu/children.json")
    @ResponseBody
    public Object getMenuList(String id) {
        Map map = new HashMap();
        try {
            List<Resource> menus = systemManageService.getResourceChildren(id);
            
            List<ResourceTreeNodeDto> menuDtos = new ArrayList<ResourceTreeNodeDto>();
            for (Resource menu : menus) {
                menuDtos.add(ResourceTreeNodeDto.from(menu));
            }
            
            map.put("data", menuDtos);
            map.put("succeed", Boolean.TRUE);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
        
        return map;
    }
    
    @RequestMapping("/menu/permission/children.json")
    @ResponseBody
    public Object getMenuPermissionList(String id, String roleId) {
        try {
            // List<Map> menus =
            // systemManageService.getMenuPermissionChildren(id,
            // roleId);
            List<Map> menus = systemManageService.getMenuOperationPermissionChildren(id,
                                                                                     roleId);
            
            List<PermissionTreeNodeDto> menuDtos = new ArrayList<PermissionTreeNodeDto>();
            for (Map menu : menus) {
                menuDtos.add(PermissionTreeNodeDto.from(menu));
            }
            
            return JsonUtils.succeedMap(menuDtos);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    @RequestMapping("/role/permission/save.json")
    @ResponseBody
    public Object saveMenuPermission(String roleId, String data) {
        try {
            List menuPermissions = JsonUtils.parseList(data);
            menuPermissions = systemManageService.saveMenuPermission(roleId,
                                                                     menuPermissions);
            
            return JsonUtils.succeedMap(menuPermissions);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    @RequestMapping("/menu/list.json")
    @ResponseBody
    public Object getMenuList(ResourceQueryParameter queryParams) {
        if (queryParams == null) {
            queryParams = new ResourceQueryParameter();
        }
        queryParams.setType("menu");
        Map map = new HashMap();
        try {
            List<Resource> menus = systemManageService.getResourceList();
            
            List<ResourceDto> menuDtos = new ArrayList<ResourceDto>();
            for (Resource menu : menus) {
                menuDtos.add(ResourceDto.from(menu));
            }
            
            map.put("data", menuDtos);
            map.put("succeed", Boolean.TRUE);
        }
        catch (Exception e) {
            logger.error(e, e);
            map.put("succeed", Boolean.FALSE);
            map.put("message", e.getMessage());
        }
        
        return map;
    }
    
    @RequestMapping("/menu/detail.do")
    public String getMenuDetail(String id, ModelMap map) {
        try {
            map.put("data",
                    ResourceDto.from(systemManageService.getResource(id)));
            map.put("succeed", Boolean.TRUE);
        }
        catch (Exception e) {
            logger.error(e, e);
            map.put("succeed", Boolean.FALSE);
            map.put("message", e.getMessage());
        }
        return "system/menu/detail";
    }
    
    @RequestMapping("/menu/detail.json")
    @ResponseBody
    public Object getResourceDetail(String id) {
        Map map = new HashMap();
        try {
            map.put("data",
                    ResourceDto.from(systemManageService.getResource(id)));
            map.put("succeed", Boolean.TRUE);
        }
        catch (Exception e) {
            logger.error(e, e);
            map.put("succeed", Boolean.FALSE);
            map.put("message", e.getMessage());
        }
        return map;
    }
    
    @RequestMapping("/log/count.json")
    @ResponseBody
    public Object getLogCount(OperateLogQueryParameter parameter) {
        parameter = initLogParameterByRole(parameter);
        try {
            int count = systemManageFinder.countOperateLog(parameter);
            return JsonUtils.succeedMap(count);
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    @RequestMapping("/log/list.json")
    @ResponseBody
    public Object getLogList(OperateLogQueryParameter parameter) {
        parameter = initLogParameterByRole(parameter);
        try {
            List<Map> list = systemManageFinder.listOperateLog(parameter);
            return JsonUtils.succeedMap(OperateLogDto.from(list));
        }
        catch (Exception e) {
            logger.error(e, e);
            return JsonUtils.failedMap(e.getMessage());
        }
    }
    
    private OperateLogQueryParameter initLogParameterByRole(OperateLogQueryParameter queryParameter) {
        if (queryParameter == null) {
            queryParameter = new OperateLogQueryParameter();
        }
        
        if (StringUtils.areBlank(queryParameter.getUserId(),
                                 queryParameter.getOrganId())) {
            queryParameter.setOrganId(SecurityUtils.currentUser().getOrganId());
        }
        return queryParameter;
    }
    
}
